package JavaDesignModel;
// 实验五 单例模式


/*
单列模式实现核心在于类中的private static Printer instance变量
静态变量声明只是"预留位置"，不涉及对象创建，因此即使静态变量编译比类声明编译先，也不会影响到类的初始化
静态变量的唯一性：每个类只有一个静态变量副本(java语言特性)
访问控制：通过私有构造器和公共获取方法控制实例化
全局访问点：通过静态方法提供统一的实例获取方式
*/

/*
//饿汉式单例实现
public class Printer {
    private static final Printer instance = new Printer();

    private Printer() {
        System.out.println("饿汉式打印机初始化完成");
    }

    public static Printer getInstance() {
        return instance;
    }

    public void print(String text) {
        System.out.println("打印内容: " + text);
    }
}


//懒汉式单例实现（非线程安全）
public class Printer {
    private static Printer instance = null;

    private Printer() {
        System.out.println("懒汉式打印机初始化完成");
    }

    public static Printer getInstance() {
        if (instance == null) {
            instance = new Printer();
        }
        return instance;
    }

    public void print(String text) {
        System.out.println("打印内容: " + text);
    }
}


//双重检查锁单例实现
public class Printer {
    private static volatile Printer instance;

    private Printer() {
        System.out.println("双重检查锁打印机初始化完成");
    }

    public static Printer getInstance() {
        if (instance == null) {
            synchronized (Printer.class) {
                if (instance == null) {
                    instance = new Printer();
                }
            }
        }
        return instance;
    }

    public void print(String text) {
        System.out.println("打印内容: " + text);
    }
}


//静态内部类单例实现
public class Printer {
    private Printer() {
        System.out.println("静态内部类打印机初始化完成");
    }

    public static Printer getInstance() {
        return Holder.instance;
    }

    private static class Holder {
        private static final Printer instance = new Printer();
    }

    public void print(String text) {
        System.out.println("打印内容: " + text);
    }
}
*/


// 线程不安全的懒汉式单例测试
class Printer {
    private static Printer instance;

    private Printer() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("打印机实例被创建，线程: " + Thread.currentThread().getName());
    }

    public static Printer getInstance() {
        if (instance == null) {
            instance = new Printer();
        }
        return instance;
    }

    public void print(String text) {
        System.out.println("打印内容: " + text);
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        Printer printer = Printer.getInstance();
        System.out.println(
                "线程 " + Thread.currentThread().getName() + " 获取的实例哈希码：" + printer.hashCode());
    }
}

public class ThreadSafetyTest {

    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        MyThread t4 = new MyThread();
        MyThread t5 = new MyThread();

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

        try {
            t1.join();
            t2.join();
            t3.join();
            t4.join();
            t5.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

